/**
 * 
 */
package com.itboye.zhujia.net;

import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.json.JSONObject;

import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.text.Spanned;
import android.util.Log;
import android.util.TimeUtils;

import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.google.gson.FieldNamingPolicy;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.itboye.zhujia.base.MyApplcation;
import com.itboye.zhujia.constants.NetPublicConstant;
import com.itboye.zhujia.util.ParamDeal;
import com.itboye.zhujia.util.String2Spanned;
import com.itboye.zhujia.util.TimesUtils;

/**
 * @author w
 * @param <T>
 *
 */
public class ByJsonRequest<E> extends XJsonRequest<E> {
	
	ByJsonRequest(String url, XRequestListener<E> listener, XErrorListener errlistener) {
		super(url, listener, errlistener);
	}
	
	ByJsonRequest(int method, String url, XRequestListener<E> listener, XErrorListener errlistener) {
		super(method, url, listener, errlistener);

	}
	

	public static class Builder<T> {
		private ByJsonRequest<T> buildRequest;
		private String url = NetPublicConstant.URL;
		private XRequestListener<T> listener;
		private XErrorListener errlistener;
		private Type expectReturnType;
		private String typekey;
		private String apiVer;
		
		private Map<String, Object> map;
		private Map<String, Object> userParam;
		private String time = TimesUtils.getStamp();
		private String notify_id = TimesUtils.getStamp();
		private String desContent ;
		
		/**
		 * 获取App的版本号
		 * @return 返回App的版本号
		 */
		private String getVersionCode()
		{
		    int appVersion=0;
			try
			{

				PackageManager pm = MyApplcation.getInstance().getPackageManager();
				PackageInfo info = pm.getPackageInfo(MyApplcation.getInstance().getPackageName(), 0);
				appVersion=info.versionCode;
			}catch(Exception e)
			{
				
			}
			return ""+appVersion;
		}
		
		
		String appv=String.valueOf(getVersionCode());
		

		public Builder() {
			map = new HashMap<String, Object>();
			userParam=new HashMap<String, Object>();
			
			// 公共参数
			map.put(NetPublicParams.APP_VERSION , getVersionCode());
			map.put(NetPublicParams.APP_TYPE, "android");
			map.put(NetPublicParams.TIME, time);
			map.put(NetPublicParams.ALG, NetPublicParams.ALG_VALUE);
			map.put(NetPublicParams.NOTIFY_ID, time);
			map.put("client_id", NetPublicParams.CLIENT_ID);
			this.url += "?client_id="+NetPublicParams.CLIENT_ID;
		}
		
		public Builder<T> addParams(Map<String,Object> params) {
			if(params != null){
				Set<String> keys =  params.keySet();
				Iterator<String> it = keys.iterator();
				while(it.hasNext()){
					
					String key = it.next();
					Object obj = params.get(key);
					userParam.put(key, obj);
				}
			}
			return this;
		}
		
		public Builder<T> param(String k,String v) {
			userParam.put(k, v);
			return this;
		}
		
		/**
		 * 
		 * @param k
		 * @param v
		 * @return
		 */
		public Builder<T> param(String k,Object v) {
			userParam.put(k, v);
			return this;
		}
		
		public Builder<T> notifyID(String notify_id){
			this.notify_id = notify_id;
			return this;
		}
		
		public Builder<T> url(String url) {
			this.url = url;
			return this;
		}

		public Builder<T> requestListener(XRequestListener<T> listener) {
			this.listener = listener;
			return this;
		}

		public Builder<T> errorListener(XErrorListener errlistener) {
			this.errlistener = errlistener;
			return this;
		}
		/**-
		 * 同时设置 type，ver，params
		 * @param typekey
		 * @param ver
		 * @param params
		 * @return
		 */
		public Builder<T> setTypeVerParams(String typekey,String ver,Map<String,Object> params) {
			this.typekey = typekey;
			this.apiVer = ver;
			this.userParam = params;
			return this;
		}
		
		public Builder<T> setTypeVerParamsAndReturnClass(String typekey,String ver,Map<String,Object> params,Type expectReturnType) {
			this.typekey = typekey;
			this.apiVer = ver;
			this.userParam = params;
			this.expectReturnType = expectReturnType;
			return this;
		}
		
		public Builder<T> typeKey(String typekey) {
			this.typekey = typekey;
			return this;
		}

		public Builder<T> apiVer(String ver) {
			this.apiVer = ver;
			return this;
		}

		public Builder<T> requestMethod(int method) {
			return this;
		}
		
		public Builder<T>  desEncode(){

			String param =  new ParamDeal().dataEncrypt(userParam);
			String sign = signInfo(param);
			this.addParams(map)
			.param(NetPublicParams.TYPE, typekey)
			.param(NetPublicParams.API_VER, apiVer)
			.param(NetPublicParams.DATA, param)
			.param(NetPublicParams.SIGN, sign);

			 Gson gson = new GsonBuilder()
					 .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
					 .registerTypeAdapter(Spanned.class, new String2Spanned())
					 .create();
			
			String jsonStr = gson.toJson(this.userParam);
			 
			Log.d("ByJsonRequest", jsonStr);
			this.desContent =  DESUtil.encode(jsonStr, NetPublicParams.CLIENT_SECERET);
			Log.d("ByJsonRequest", desContent);
			
			return this;
		}
		
		/**
		 * 设置返回数据类型
		 * @param expectClass
		 * @return
		 */
		public Builder<T>  setReturnDataType(Type expectReturnType){
			this.expectReturnType = expectReturnType;
			return this;
		}
		

		/**
		 * 创建 MyJsonRequest对象
		 * @return
		 */
		public ByJsonRequest<T> desEncodeThenBuildAndSend() {
			MyApplcation.addRequest(this.desEncode().build());
			return this.buildRequest;
		}
		
		/**
		 * 创建 MyJsonRequest对象
		 * @return
		 */
		public ByJsonRequest<T> build() {
			if (listener == null) {
				System.err.println("XRequestListener == null !");
			}
			if (errlistener == null) {
				System.err.println("ErrorListener == null !");
			}

			if (null == typekey) {
				throw new RuntimeException("typekey can not be null ! you should use typeKey(String typekey) ");
			}
			
			if (null == apiVer) {
				throw new RuntimeException("apiVer can not be null ! you should use apiVer(String ver) ");
			}

			buildRequest = new ByJsonRequest<T>(url,listener,errlistener);
			buildRequest.setRetryPolicy(new DefaultRetryPolicy(10000, 
					DefaultRetryPolicy.DEFAULT_MAX_RETRIES, 
					DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
			buildRequest.setExpectReturnType(expectReturnType);
			buildRequest.addParam(NetPublicParams.ITBOYE, desContent);
			buildRequest.setMethod(Method.POST);
			
			//增加SocketLog调试
			buildRequest.addHeader("SocketLog", "SocketLog(tabid=2&client_id=slog_fc68e9)");
			return buildRequest;

		}

		private String signInfo(String userInf) {
			
			ParamDeal operate = new ParamDeal();
			String sign = operate.getMD5Sign(time, typekey, userInf, NetPublicParams.CLIENT_SECERET, notify_id);

			return sign;
		}

	}
}